import { message } from "antd";
import axios, { AxiosRequestConfig } from "axios";
import store from "store";
import { history } from "umi";

export type Response<T> = {
  code: number;
  message: string;
  t?: T;
};

const handleAxiosError = (url: string, error: any) => {
  const { response, request, message: msg } = error;
  let unknownMessage = "未知错误";
  if (response) {
    const { status, data = {}, statusText } = response;
    if (status === "auth_invalid" && !url.includes("login")) {
      store.set("routeList", []);
      store.set("user", {});
      history.replace({
        pathname: "/login",
      });
      unknownMessage = "登录失效，请重新登录";
    } else {
      unknownMessage = data.message || statusText;
    }
  } else if (request) {
    unknownMessage = "请求未响应";
  } else if (String(msg) === "cancel_request_message") {
    unknownMessage = "请求取消";
  } else {
    unknownMessage = msg;
  }

  return unknownMessage;
};

const { CancelToken } = axios;
const cancelRequest = new Map();

const Request: <T>(
  config: AxiosRequestConfig
) => Promise<{ message: string; data?: T }> = async (config) => {
  const { url = "", headers = {} } = config;

  console.log(headers["Content-Type"], 'headers["Content-Type"]');

  const user = store.get("user") || {};
  const requestConfig: AxiosRequestConfig = {
    ...config,
    baseURL: config?.baseURL || "",
    url,
    cancelToken: config.cancelToken
      ? config.cancelToken
      : new CancelToken((cancel) => {
          cancelRequest.set(Symbol(Date.now()), {
            pathname: window.location.pathname,
            cancel,
          });
        }),
    headers: {
      ...headers,
      "Content-Type": headers["Content-Type"] || "application/json",
      Authorization: `Bearer ${user?.token}`,
    },
  };

  console.log(requestConfig, "requestConfig");

  try {
    const response = await axios(requestConfig);
    const { statusText, data, status, headers: resHeader } = response;
    return {
      success: true,
      message: statusText,
      status: status,
      headers: resHeader,
      data,
    };
  } catch (error: any) {
    const { response } = error;
    const errMsg = handleAxiosError(url, error);
    console.error("HTTP请求失败，请稍后重试" + config.url || "", errMsg);
    return {
      success: false,
      message: errMsg,
      status: response?.status || 500,
    };
  }
};

const requestWithCodeMsg = async <T>(options: AxiosRequestConfig) => {
  const res = await Request<Response<T>>(options);
  const { data, message: msg } = res;
  if (data) {
    return data;
  } else if (msg) {
    message.error(msg);
  }
  return undefined;
};

const normalRequest = async <T>(
  options: AxiosRequestConfig
): Promise<T | undefined> => {
  const res = await requestWithCodeMsg<T>(options);
  if (res) {
    const { code, message: msg, t } = res;
    if (code === 200) {
      return t;
    }
    message.error(msg);
  }
  return undefined;
};

const flagRequest = async (options: AxiosRequestConfig): Promise<boolean> => {
  const res = await requestWithCodeMsg<boolean>(options);
  if (res) {
    const { code, message: msg, t } = res;
    if (code === 0) {
      return true;
    }
    message.error(msg);
  }
  return false;
};

export default Request;
export { normalRequest, flagRequest, requestWithCodeMsg };
